home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * An SGI 4D driver using GL (experimental adaptive isocurve renderer.). *
- * *
- * Written by: Gershon Elber Ver 0.1, June 1993. *
- *****************************************************************************/
-
- #include <gl/gl.h>
- #include <gl/device.h>
-
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include <ctype.h>
- #include "irit_sm.h"
- #include "genmat.h"
- #include "config.h"
- #include "iritprsr.h"
- #include "allocate.h"
- #include "attribut.h"
- #include "ip_cnvrt.h"
- #include "cagd_lib.h"
- #include "iritgrap.h"
- #include "irit_soc.h"
-
- /* Interactive menu setup structure: */
- #define INTERACT_NUM_OF_STRINGS 4
- #define INTERACT_NUM_OF_SUB_WNDWS 16
-
- typedef struct InteractString {
- RealType X, Y;
- int Color;
- char *Str;
- } InteractString;
- typedef struct InteractSubWindow {
- RealType X, Y; /* Center points. */
- int Color;
- IGGraphicEventType Event;
- int TextInside; /* If TRUE, Str will be in window, otherwise left to it. */
- char *Str;
- } InteractSubWindow;
- typedef struct InteractWindowStruct { /* The interactive menu structures. */
- /* Rotate, Translate, Scale strings: */
- InteractString Strings[INTERACT_NUM_OF_STRINGS];
- InteractSubWindow SubWindows[INTERACT_NUM_OF_SUB_WNDWS];
- } InteractWindowStruct;
-
- #define INTERACT_SUB_WINDOW_WIDTH 0.8 /* Relative to window size. */
- #define INTERACT_SUB_WINDOW_HEIGHT 0.04
-
- static int
- GlblStateMenu = 0,
- GlblRuledSrfApprox = FALSE;
-
- static long
- TransWinID = 0,
- TransWinWidth = 100,
- TransWinWidth2 = 50,
- TransWinHeight = 100,
- TransWinLow = 0,
- TransWinLeft = 0,
- ViewWinID = 0,
- ViewWinWidth = 100,
- ViewWinWidth2 = 50,
- ViewWinHeight = 100,
- ViewWinHeight2 = 50,
- ViewWinLow = 0,
- ViewWinLeft = 0;
-
- static RealType
- GlblAdapIsoEps = 0.05,
- GlblRuledSrfEps = 0.02;
-
- /* Interactive mode menu set up structure is define below: */
- static InteractWindowStruct InteractMenu = {
- { { 0.5, 0.81, IG_IRIT_RED, "Rotate" },
- { 0.5, 0.65, IG_IRIT_GREEN, "Translate" },
- { 0.5, 0.49, IG_IRIT_CYAN, "Scale" },
- { 0.5, 0.41, IG_IRIT_LIGHTGREEN, "Clip Plane" },
- },
- { { 0.5, 0.93, IG_IRIT_YELLOW, IG_EVENT_SCR_OBJ_TGL, TRUE, "Screen Coords." },
- { 0.5, 0.87, IG_IRIT_BLUE, IG_EVENT_PERS_ORTHO_TGL, TRUE, "Perspective" },
- { 0.5, 0.83, IG_IRIT_BLUE, IG_EVENT_PERS_ORTHO_Z, FALSE, "Z" },
- { 0.5, 0.75, IG_IRIT_RED, IG_EVENT_ROTATE_X, FALSE, "X" }, /* Rot */
- { 0.5, 0.71, IG_IRIT_RED, IG_EVENT_ROTATE_Y, FALSE, "Y" },
- { 0.5, 0.67, IG_IRIT_RED, IG_EVENT_ROTATE_Z, FALSE, "Z" },
- { 0.5, 0.59, IG_IRIT_GREEN, IG_EVENT_TRANSLATE_X, FALSE, "X" }, /* Trans */
- { 0.5, 0.55, IG_IRIT_GREEN, IG_EVENT_TRANSLATE_Y, FALSE, "Y" },
- { 0.5, 0.51, IG_IRIT_GREEN, IG_EVENT_TRANSLATE_Z, FALSE, "Z" },
- { 0.5, 0.43, IG_IRIT_CYAN, IG_EVENT_SCALE, FALSE, "" }, /* Scale */
- { 0.5, 0.35, IG_IRIT_LIGHTGREEN, IG_EVENT_NEAR_CLIP, FALSE, "" },
- { 0.5, 0.31, IG_IRIT_LIGHTGREEN, IG_EVENT_FAR_CLIP, FALSE, "" },
-
- { 0.5, 0.20, IG_IRIT_YELLOW, IG_EVENT_SAVE_MATRIX, TRUE, "Save Matrix" },
- { 0.5, 0.13, IG_IRIT_YELLOW, IG_EVENT_PUSH_MATRIX, TRUE, "Push Matrix" },
- { 0.5, 0.09, IG_IRIT_YELLOW, IG_EVENT_POP_MATRIX, TRUE, "Pop Matrix" },
- { 0.5, 0.03, IG_IRIT_WHITE, IG_EVENT_QUIT, TRUE, "Quit" },
- }
- };
-
- static short Colors[IG_MAX_COLOR + 1][3] =
- {
- { 0, 0, 0 }, /* 0. BLACK */
- { 0, 0, 170 }, /* 1. BLUE */
- { 0, 170, 0 }, /* 2. GREEN */
- { 0, 170, 170 }, /* 3. CYAN */
- { 170, 0, 0 }, /* 4. RED */
- { 170, 0, 170 }, /* 5. MAGENTA */
- { 170, 170, 0 }, /* 6. BROWN */
- { 170, 170, 170 }, /* 7. LIGHTGREY */
- { 85, 85, 85 }, /* 8. DARKGRAY */
- { 85, 85, 255 }, /* 9. LIGHTBLUE */
- { 85, 255, 85 }, /* 10. LIGHTGREEN */
- { 85, 255, 255 }, /* 11. LIGHTCYAN */
- { 255, 85, 85 }, /* 12. LIGHTRED */
- { 255, 85, 255 }, /* 13. LIGHTMAGENTA */
- { 255, 255, 85 }, /* 14. YELLOW */
- { 255, 255, 255 } /* 15. WHITE */
- };
-
- static void IGDrawPolyNormal(IPObjectStruct *PObj, int HasNormals);
- static IPPolygonStruct *IritSurface2AdapIso(CagdSrfStruct *Srf,
- CagdSrfDirType Dir,
- RealType Eps, int SamplesPerCurve);
- static void SetColorIndex(int c);
- static void SetColorRGB(int Color[3]);
- static void ClearViewArea(void);
- static void SetTransformWindow(void);
- static void RedrawTransformWindow(void);
- static void SetViewWindow(void);
- static void RedrawViewWindow(void);
- static int IsAbortKeyPressed(void);
- static void ProcessEvent(IGGraphicEventType Event, RealType ChangeFactor);
- static IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor);
- static void DrawText(char *Str, long PosX, long PosY);
-
- /****************************************************************************
- * Pop up all windows, read input and display. *
- ****************************************************************************/
- void main(int argc, char **argv)
- {
- RealType ChangeFactor;
- IGGraphicEventType Event;
- IPObjectStruct *PObjects;
-
- IGConfigureGlobals("xgladap", argc, argv);
-
- SetViewWindow();
- RedrawViewWindow();
- SetTransformWindow();
- RedrawTransformWindow();
-
- qdevice(LEFTMOUSE);
- qdevice(MIDDLEMOUSE);
- qdevice(RIGHTMOUSE);
-
- /* The default drawing window is the view window. */
- winset(ViewWinID);
-
- setbell(1); /* Make it short. */
-
- IGCreateStateMenu();
-
- if (!IGGlblStandAlone)
- SocClientCreateSocket();
-
- while ((Event = GetGraphicEvent(&ChangeFactor)) != IG_EVENT_QUIT) {
- if (IGProcessEvent(Event, ChangeFactor * IGGlblChangeFactor))
- RedrawViewWindow();
- }
-
- if (!IGGlblStandAlone)
- SocClientCloseSocket();
- }
-
- /*****************************************************************************
- * Construct global pop up menu. *
- *****************************************************************************/
- void IGCreateStateMenu(void)
- {
- if (GlblStateMenu)
- freepup(GlblStateMenu);
-
- GlblStateMenu = newpup();
-
- addtopup(GlblStateMenu, " Set Up %t", 0);
- addtopup(GlblStateMenu, "Oops!%l", 0);
- addtopup(GlblStateMenu, "More Sensitive", 0);
- addtopup(GlblStateMenu, "Less Sensitive%l", 0);
- addtopup(GlblStateMenu, IGGlblTransformMode == IG_TRANS_SCREEN ?
- "Screen Trans." : "Object Trans", 0);
- addtopup(GlblStateMenu, IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
- "Perspective" : "Orthographic", 0);
- addtopup(GlblStateMenu,
- IGGlblDepthCue ? "Depth Cue" : "No Depth Cue", 0);
- addtopup(GlblStateMenu,
- IGGlblDrawSolid ? "Draw Solid" : "Draw Wireframe", 0);
- addtopup(GlblStateMenu,
- IGGlblDoDoubleBuffer ? "Double Buffer" : "Single Buffer", 0);
- addtopup(GlblStateMenu,
- IGGlblAntiAliasing ? "Anti Aliasing" : "No Anti Aliasing", 0);
- addtopup(GlblStateMenu,
- IGGlblDrawInternal ? "Draw Internal Edges" : "No Internal Edges", 0);
- addtopup(GlblStateMenu,
- IGGlblDrawVNormal ? "Draw Vrtx Normals" : "No Vrtx Normals", 0);
- addtopup(GlblStateMenu,
- IGGlblDrawPNormal ? "Draw Poly Normals" : "No Poly Normals", 0);
- addtopup(GlblStateMenu,
- IGGlblDrawSurfaceMesh ? "Draw Surface Mesh" : "No Surface Mesh", 0);
- addtopup(GlblStateMenu,
- IGGlblDrawSurfacePoly ? "Surface Polygons" : "Surface Isolines", 0);
- addtopup(GlblStateMenu,
- IGGlblFourPerFlat ? "Four Per Flat%l" : "Two Per Flat%l", 0);
- addtopup(GlblStateMenu, "More Isolines", 0);
- addtopup(GlblStateMenu, "Less Isolines%l", 0);
- addtopup(GlblStateMenu, "Finer Approx.", 0);
- addtopup(GlblStateMenu, "Coarser Approx.%l", 0);
- addtopup(GlblStateMenu, "Longer Vectors.", 0);
- addtopup(GlblStateMenu, "Shorter Vectors%l", 0);
- addtopup(GlblStateMenu, "Thicker Lines.", 0);
- addtopup(GlblStateMenu, "Thinner Lines%l", 0);
- addtopup(GlblStateMenu, "Finer Adap. Iso.", 0);
- addtopup(GlblStateMenu, "Coarser Adap. Iso.", 0);
- addtopup(GlblStateMenu, "Finer Ruled Srf.", 0);
- addtopup(GlblStateMenu, "Coarser Ruled Srf.", 0);
- addtopup(GlblStateMenu,
- GlblRuledSrfApprox ? "Direct Adap. Iso." : "Ruled Adap. Iso.", 0);
- addtopup(GlblStateMenu, "Adap. Iso. Dir.", 0);
- }
-
- /****************************************************************************
- * Draw a Point/Vector object using current modes and transformations. *
- ****************************************************************************/
- void IGDrawPtVec(IPObjectStruct *PObj)
- {
- static PointType
- Zero = { 0.0, 0.0, 0.0 };
- int i;
- PointType Ends[6];
- RealType
- *Pt = PObj -> U.Pt;
-
- IGSetColorObj(PObj);
-
- for (i = 0; i < 6; i++)
- PT_COPY(Ends[i], Pt);
-
- Ends[0][0] -= IG_POINT_WIDTH;
- Ends[1][0] += IG_POINT_WIDTH;
- Ends[2][1] -= IG_POINT_WIDTH;
- Ends[3][1] += IG_POINT_WIDTH;
- Ends[4][2] -= IG_POINT_WIDTH;
- Ends[5][2] += IG_POINT_WIDTH;
-
- for (i = 0; i < 6; i += 2) {
- bgnline();
- v3d(Ends[i]);
- v3d(Ends[i+1]);
- endline();
- }
-
- if (IP_IS_VEC_OBJ(PObj)) {
- bgnline();
- v3d(Pt);
- v3d(Zero);
- endline();
- }
- }
-
- /****************************************************************************
- * Draw a Poly object using current modes and transformations. *
- ****************************************************************************/
- void IGDrawPoly(IPObjectStruct *PObj)
- {
- IGDrawPolyNormal(PObj, FALSE);
- }
-
- /****************************************************************************
- * Draw a Poly object using current modes and transformations. *
- * This function allowes polylines to have normals so we can actually draw *
- * the adaptive isolines to render a surface. *
- ****************************************************************************/
- static void IGDrawPolyNormal(IPObjectStruct *PObj, int HasNormals)
- {
- IPVertexStruct *V;
- IPPolygonStruct
- *Pl = PObj -> U.Pl;
-
- IGSetColorObj(PObj);
-
- if (IP_IS_POLYLINE_OBJ(PObj)) {
- for (; Pl != NULL; Pl = Pl -> Pnext) {
- bgnline();
- for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
- if (HasNormals) {
- float n[3];
-
- n[0] = V -> Normal[0];
- n[1] = V -> Normal[1];
- n[2] = V -> Normal[2];
- n3f(n);
- }
- v3d(V -> Coord);
- }
- endline();
- }
- }
- else if (IP_IS_POINTLIST_OBJ(PObj)) {
- for (; Pl != NULL; Pl = Pl -> Pnext) {
- for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
- int i;
- PointType Ends[6];
- RealType
- *Pt = V -> Coord;
-
- for (i = 0; i < 6; i++)
- PT_COPY(Ends[i], Pt);
-
- Ends[0][0] -= IG_POINT_WIDTH;
- Ends[1][0] += IG_POINT_WIDTH;
- Ends[2][1] -= IG_POINT_WIDTH;
- Ends[3][1] += IG_POINT_WIDTH;
- Ends[4][2] -= IG_POINT_WIDTH;
- Ends[5][2] += IG_POINT_WIDTH;
-
- for (i = 0; i < 6; i += 2) {
- bgnline();
- v3d(Ends[i]);
- v3d(Ends[i+1]);
- endline();
- }
- }
- }
- }
- else if (IP_IS_POLYGON_OBJ(PObj)) {
- int i, j,
- NumOfVertices;
- PointType PNormal, VNormal;
-
- for (; Pl != NULL; Pl = Pl -> Pnext) {
- if (IGGlblDrawPNormal) {
- NumOfVertices = 0;
- PNormal[0] = PNormal[1] = PNormal[2] = 0.0;
- }
-
- if (IGGlblDrawSolid) {
- bgnpolygon();
- for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
- float n[3];
-
- n[0] = V -> Normal[0];
- n[1] = V -> Normal[1];
- n[2] = V -> Normal[2];
- n3f(n);
- v3d(V -> Coord);
-
- if (IGGlblDrawPNormal) {
- for (j = 0; j < 3; j++)
- PNormal[j] += V -> Coord[j];
- NumOfVertices++;
- }
- }
- endpolygon();
- }
- else {
- bgnline();
- for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
- v3d(V -> Coord);
- if (IP_IS_INTERNAL_VRTX(V) && !IGGlblDrawInternal) {
- endline();
- bgnline();
- }
-
- if (IGGlblDrawPNormal) {
- for (j = 0; j < 3; j++)
- PNormal[j] += V -> Coord[j];
- NumOfVertices++;
- }
- }
- v3d(Pl -> PVertex -> Coord);
- endline();
- }
-
- if (IGGlblDrawPNormal && IP_HAS_PLANE_POLY(Pl)) {
- bgnline();
- for (i = 0; i < 3; i++)
- PNormal[i] /= NumOfVertices;
- v3d(PNormal);
- for (i = 0; i < 3; i++)
- PNormal[i] += Pl -> Plane[i] * IGGlblNormalLen;
- v3d(PNormal);
- endline();
- }
-
- if (IGGlblDrawVNormal) {
- for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
- if (IP_HAS_NORMAL_VRTX(V)) {
- for (j = 0; j < 3; j++)
- VNormal[j] = V -> Coord[j] +
- V -> Normal[j] * IGGlblNormalLen;
- bgnline();
- v3d(V ->Coord);
- v3d(VNormal);
- endline();
- }
- }
- }
- }
- }
- }
-
- /****************************************************************************
- * Draw a single Surface object using current modes and transformations. *
- * Surface must be with either E3 or P3 point type and must be NURB. *
- * Control points in SGI's format must be found in "_ctlpoints" attribute. *
- ****************************************************************************/
- void IGDrawSurface(IPObjectStruct *PObj)
- {
- IPObjectStruct *PObjPolylines, *PObjCtlMesh, *PObjPolygons;
- IPPolygonStruct *PPolylines, *PCtlMesh, *PPolygons, *PPolyTemp;
-
- if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_isoline")) == NULL) {
- CagdSrfStruct *Srf,
- *Srfs = PObj -> U.Srfs;
-
- PObjPolylines = IPAllocObject("", IP_OBJ_POLY, NULL);
- PObjPolylines -> Attrs = AttrCopyAttributes(PObj -> Attrs);
- IP_SET_POLYLINE_OBJ(PObjPolylines);
- for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
- int NumOfIso[2];
-
- NumOfIso[0] = -IGGlblNumOfIsolines;
- NumOfIso[1] = -IGGlblNumOfIsolines;
- PPolylines = IritSurface2Polylines(Srf, NumOfIso,
- IGGlblSamplesPerCurve);
-
- for (PPolyTemp = PPolylines;
- PPolyTemp -> Pnext;
- PPolyTemp = PPolyTemp -> Pnext);
- PPolyTemp -> Pnext = PObjPolylines -> U.Pl;
- PObjPolylines -> U.Pl = PPolylines;
- }
- AttrSetObjectObjAttrib(PObj, "_isoline", PObjPolylines);
- }
-
- if (IGGlblDrawSolid) {
- if (IGGlblDrawSurfacePoly) {
- if ((PObjPolygons = AttrGetObjectObjAttrib(PObj, "_polygons"))
- == NULL) {
- CagdSrfStruct *Srf,
- *Srfs = PObj -> U.Srfs;
-
- PObjPolygons = IPAllocObject("", IP_OBJ_POLY, NULL);
- PObjPolygons -> Attrs = AttrCopyAttributes(PObj -> Attrs);
- IP_SET_POLYGON_OBJ(PObjPolygons);
-
- for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
- PPolygons = IritSurface2Polygons(Srf, IGGlblFourPerFlat,
- 1 << IGGlblFineNess, FALSE);
-
- if (PPolygons) {
- for (PPolyTemp = PPolygons;
- PPolyTemp -> Pnext;
- PPolyTemp = PPolyTemp -> Pnext);
- PPolyTemp -> Pnext = PObjPolygons -> U.Pl;
- PObjPolygons -> U.Pl = PPolygons;
- }
- }
- AttrSetObjectObjAttrib(PObj, "_polygons", PObjPolygons);
- }
-
- IGDrawPolyNormal(PObjPolygons, TRUE);
- }
- else {
- if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_adap_iso"))
- == NULL) {
- CagdSrfStruct *Srf,
- *Srfs = PObj -> U.Srfs;
-
- PObjPolylines = IPAllocObject("", IP_OBJ_POLY, NULL);
- PObjPolylines -> Attrs = AttrCopyAttributes(PObj -> Attrs);
- IP_SET_POLYLINE_OBJ(PObjPolylines);
-
- for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
- PPolylines = IritSurface2AdapIso(Srf, IGGlblAdapIsoDir,
- GlblAdapIsoEps,
- IGGlblSamplesPerCurve);
-
- if (PPolylines) {
- for (PPolyTemp = PPolylines;
- PPolyTemp -> Pnext;
- PPolyTemp = PPolyTemp -> Pnext);
- PPolyTemp -> Pnext = PObjPolylines -> U.Pl;
- PObjPolylines -> U.Pl = PPolylines;
- }
- }
- AttrSetObjectObjAttrib(PObj, "_adap_iso", PObjPolylines);
- }
-
- IGDrawPolyNormal(PObjPolylines, TRUE);
- }
- }
- else
- IGDrawPolyNormal(PObjPolylines, FALSE);
-
- if (IGGlblDrawSurfaceMesh) {
- if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_ctlmesh"))
- == NULL) {
- CagdSrfStruct *Srf,
- *Srfs = PObj -> U.Srfs;
-
- PObjCtlMesh = IPAllocObject("", IP_OBJ_POLY, NULL);
- PObjCtlMesh -> Attrs = AttrCopyAttributes(PObj -> Attrs);
- IP_SET_POLYLINE_OBJ(PObjCtlMesh);
- for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
- PCtlMesh = IritSurface2CtlMesh(Srf);
-
- for (PPolyTemp = PCtlMesh;
- PPolyTemp -> Pnext;
- PPolyTemp = PPolyTemp -> Pnext);
- PPolyTemp -> Pnext = PObjCtlMesh -> U.Pl;
- PObjCtlMesh -> U.Pl = PCtlMesh;
- }
- AttrSetObjectObjAttrib(PObj, "_ctlmesh", PObjCtlMesh);
- }
-
- IGDrawPolyNormal(AttrGetObjectObjAttrib(PObj, "_ctlmesh"), FALSE);
- }
- }
-
- /****************************************************************************
- * Create an adaptive isocurve coverage to a given surface. *
- ****************************************************************************/
- static IPPolygonStruct *IritSurface2AdapIso(CagdSrfStruct *Srf,
- CagdSrfDirType Dir,
- RealType Eps, int SamplesPerCurve)
- {
- CagdCrvStruct *Coverage, *OneCoverage, *Crv;
- IPPolygonStruct
- *IsoPoly = NULL;
- CagdSrfStruct *NSrf;
-
- if (Dir == CAGD_NO_DIR)
- Dir = Srf -> UOrder == 2 ? CAGD_CONST_U_DIR : CAGD_CONST_V_DIR;
-
- fprintf(stderr, "Generating adaptive isocurve coverage...\n");
- if (GlblRuledSrfApprox) {
- int IsBspline = TRUE;
- CagdSrfStruct *RuledSrfs, *NormalSrf, *TSrf;
-
- if (CAGD_IS_BEZIER_SRF(Srf)) {
- IsBspline = FALSE;
- Srf = CnvrtBezier2BsplineSrf(Srf);
- }
- RuledSrfs = CagdPiecewiseRuledSrfApprox(Srf, TRUE, GlblRuledSrfEps,
- Dir);
-
- Coverage = NULL;
- NormalSrf = CagdSrfNormalSrf(Srf);
- for (TSrf = RuledSrfs; TSrf != NULL; TSrf = TSrf -> Pnext) {
- CagdRType UMin, UMax, VMin, VMax;
-
- CagdSrfDomain(TSrf, &UMin, &UMax, &VMin, &VMax);
- if (Dir == CAGD_CONST_V_DIR)
- NSrf = CagdSrfRegionFromSrf(NormalSrf, UMin, UMax,
- CAGD_CONST_U_DIR);
- else
- NSrf = CagdSrfRegionFromSrf(NormalSrf, VMin, VMax,
- CAGD_CONST_V_DIR);
- OneCoverage = CagdAdapIsoExtract(TSrf, NSrf, Dir,
- Eps, FALSE, FALSE);
- CagdSrfFree(NSrf);
-
- for (Crv = OneCoverage; Crv -> Pnext != NULL; Crv = Crv -> Pnext);
- Crv -> Pnext = Coverage;
- Coverage = OneCoverage;
- fprintf(stderr, "Done with one ruled surface approximation.\n");
- }
- CagdSrfFreeList(RuledSrfs);
- CagdSrfFree(NormalSrf);
- if (!IsBspline)
- CagdSrfFree(Srf);
-
- /* Scan the adaptive isoline list. Note that normal curve is paired */
- /* after Euclidean curve, so we can step two curves at a time. */
- for (Crv = Coverage; Crv != NULL; Crv = Crv -> Pnext -> Pnext) {
- CagdCrvStruct
- *NCrv = Crv -> Pnext;
- IPPolygonStruct
- *Poly = IritCurve2Polylines(Crv, 1);
- RealType
- *Nrml1 = Poly -> PVertex -> Normal,
- *Nrml2 = Poly -> PVertex -> Pnext -> Normal;
- CagdCoerceToE3(Nrml1, NCrv -> Points, 0, NCrv -> PType);
- CagdCoerceToE3(Nrml2, NCrv -> Points, NCrv -> Length - 1,
- NCrv -> PType);
- PT_NORMALIZE(Nrml1);
- PT_SCALE(Nrml1, -1.0);
- PT_NORMALIZE(Nrml2);
- PT_SCALE(Nrml2, -1.0);
-
- Poly -> Pnext = IsoPoly;
- IsoPoly = Poly;
- }
- }
- else {
- NSrf = CagdSrfNormalSrf(Srf);
-
- Coverage = CagdAdapIsoExtract(Srf, NSrf, Dir, Eps, FALSE, FALSE);
- fprintf(stderr,
- "Done with adaptive isocurve surface approximation.\n");
-
- CagdSrfFree(NSrf);
-
- /* Scan the adaptive isoline list. Note that normal curve is paired */
- /* after Euclidean curve, so we can step two curves at a time. */
- for (Crv = Coverage; Crv != NULL; Crv = Crv -> Pnext -> Pnext) {
- IPVertexStruct *VP, *VN;
- CagdCrvStruct
- *NCrv = Crv -> Pnext;
- IPPolygonStruct
- *Poly = IritCurve2Polylines(Crv, IGGlblSamplesPerCurve),
- *NPoly = IritCurve2Polylines(Crv -> Pnext, IGGlblSamplesPerCurve);
-
- for (VP = Poly -> PVertex, VN = NPoly -> PVertex;
- VP != NULL;
- VP = VP -> Pnext, VN = VN -> Pnext) {
- PT_COPY(VP -> Normal, VN -> Coord);
- PT_NORMALIZE(VP -> Normal);
- PT_SCALE(VP -> Normal, -1.0);
- }
-
- IPFreePolygonList(NPoly);
-
- Poly -> Pnext = IsoPoly;
- IsoPoly = Poly;
- }
- }
-
- CagdCrvFreeList(Coverage);
-
- return IsoPoly;
- }
-
- /****************************************************************************
- * Routine to set the color according to the given object's color. *
- ****************************************************************************/
- void IGSetColorObj(IPObjectStruct *PObj)
- {
- int c, Color[3];
-
- if (AttrGetObjectRGBColor(PObj, &Color[0], &Color[1], &Color[2])) {
- SetColorRGB(Color);
- }
- else if ((c = AttrGetObjectColor(PObj)) != IP_ATTR_NO_COLOR) {
- SetColorIndex(c);
- }
- else {
- /* Use white as default color: */
- SetColorIndex(IG_IRIT_WHITE);
- }
- }
-
- /****************************************************************************
- * Routine to set the color according to the given color index. *
- ****************************************************************************/
- static void SetColorIndex(int c)
- {
- int Color[3];
-
- if (c < 0 || c > IG_MAX_COLOR)
- c = IG_IRIT_WHITE;
-
- Color[0] = Colors[c][0];
- Color[1] = Colors[c][1];
- Color[2] = Colors[c][2];
-
- SetColorRGB(Color);
- }
-
- /****************************************************************************
- * Routine to set the color according to the given RGB values. *
- ****************************************************************************/
- static void SetColorRGB(int Color[3])
- {
- int i;
- static float
- Ambient = 0.25,
- Diffuse = 0.75,
- Specular = 1.0;
- static float
- Material[] = {
- AMBIENT, 0.25, 0.25, 0.25,
- DIFFUSE, 0.75, 0.75, 0.75,
- SPECULAR, 1.00, 1.00, 1.00,
- SHININESS, 50,
- LMNULL
- };
-
- c3i((long *) Color);
- if (IGGlblDepthCue)
- lRGBrange(0, 0, 0, Color[0], Color[1], Color[2], 0x0, 0x7fffff);
-
- /* Prepare material structure in this color and select it. */
- for (i = 0; i < 3; i++) {
- Material[1 + i] = Ambient * Color[i] / 255.0;
- Material[5 + i] = Diffuse * Color[i] / 255.0;
- Material[9 + i] = Specular * Color[i] / 255.0;
- }
- lmdef(DEFMATERIAL, 1, sizeof(Material) / sizeof(float), Material);
- }
-
- /*****************************************************************************
- * Set up and draw a transformation window. *
- *****************************************************************************/
- static void SetTransformWindow(void)
- {
- long PrefPos[4];
-
- #ifndef _AIX
- foreground();
- #endif
-
- if (sscanf(IGGlblTransPrefPos, "%ld, %ld, %ld, %ld",
- &PrefPos[0], &PrefPos[1], &PrefPos[2], &PrefPos[3]) == 4)
- prefposition(PrefPos[0], PrefPos[1], PrefPos[2], PrefPos[3]);
- else if (sscanf(IGGlblTransPrefPos, "%ld, %ld",
- &PrefPos[0], &PrefPos[1]) == 2)
- prefsize(PrefPos[0], PrefPos[1]);
- winopen("Poly3dTrans");
- winconstraints();
- wintitle("xGLdrvs");
- RGBmode();
- gconfig();
- getorigin(&TransWinLeft, &TransWinLow);
- getsize(&TransWinWidth, &TransWinHeight);
- TransWinWidth2 = TransWinWidth / 2;
- TransWinID = winget();
-
- SetColorRGB(IGGlblBackGroundColor);
- clear();
-
- /* This is wierd. without the sleep the gl get mixed up between the two */
- /* windows. If you have any idea why, let me know... */
- sleep(1);
- }
-
- /*****************************************************************************
- * Set up and draw a transformation window. *
- *****************************************************************************/
- static void RedrawTransformWindow(void)
- {
- int i;
- long SubTransPosX, SubTransPosY, SubTransWidth, SubTransHeight;
-
- /* Make sure the menu is consistent with internatal data. */
- InteractMenu.SubWindows[0].Str =
- IGGlblTransformMode == IG_TRANS_OBJECT ? "Object Coords."
- : "Screen Coords.";
- InteractMenu.SubWindows[1].Str =
- IGGlblViewMode == IG_VIEW_PERSPECTIVE ? "Perspective" : "Orthographic";
-
- winset(TransWinID); /* Draw in the transformation window. */
-
- SubTransWidth = (int) (TransWinWidth * INTERACT_SUB_WINDOW_WIDTH);
- SubTransHeight = (int) (TransWinHeight * INTERACT_SUB_WINDOW_HEIGHT);
- SubTransPosX = (TransWinWidth - SubTransWidth) / 2;
-
- SetColorRGB(IGGlblBackGroundColor);
- clear();
-
- for (i = 0; i < INTERACT_NUM_OF_SUB_WNDWS; i++) {
- SetColorIndex(InteractMenu.SubWindows[i].Color);
- SubTransPosY = (int) (TransWinHeight * InteractMenu.SubWindows[i].Y);
-
- move2i(SubTransPosX, SubTransPosY);
- draw2i(SubTransPosX + SubTransWidth, SubTransPosY);
- draw2i(SubTransPosX + SubTransWidth, SubTransPosY + SubTransHeight);
- draw2i(SubTransPosX, SubTransPosY + SubTransHeight);
- draw2i(SubTransPosX, SubTransPosY);
- if (InteractMenu.SubWindows[i].TextInside) {
- DrawText(InteractMenu.SubWindows[i].Str,
- TransWinWidth / 2,
- SubTransPosY + SubTransHeight / 2);
- }
- else {
- DrawText(InteractMenu.SubWindows[i].Str,
- (TransWinWidth - SubTransWidth) / 3,
- SubTransPosY + SubTransHeight / 2);
- move2i(SubTransPosX + SubTransWidth / 2, SubTransPosY);
- draw2i(SubTransPosX + SubTransWidth / 2,
- SubTransPosY + SubTransHeight);
- }
- }
-
- for (i = 0; i < INTERACT_NUM_OF_STRINGS; i++) {
- SetColorIndex(InteractMenu.Strings[i].Color);
- DrawText(InteractMenu.Strings[i].Str,
- (int) (InteractMenu.Strings[i].X * TransWinWidth),
- (int) (InteractMenu.Strings[i].Y * TransWinHeight));
- }
-
- winset(ViewWinID); /* Go back to the default drawing window. */
- }
-
- /*****************************************************************************
- * Routine to clear the viewing area. *
- *****************************************************************************/
- static void ClearViewArea(void)
- {
- SetColorRGB(IGGlblBackGroundColor);
- clear();
- mmode(MVIEWING);
- shademodel(GOURAUD);
- linewidth(IGGlblLineWidth);
-
- if (APX_EQ(IGGlblZMinClip, IGGlblZMaxClip))
- IGGlblZMaxClip += EPSILON;
- ortho(-1.0, 1.0, -1.0, 1.0, IGGlblZMinClip, IGGlblZMaxClip);
-
- if (winget() == ViewWinID) {
- /* activate zbuffer only if we are in solid drawing mode. */
- if (IGGlblDrawSolid) {
- /* Define necessary staff for Lighting. */
- lmbind(MATERIAL, 1);
- lmbind(LMODEL, 1);
- lmbind(LIGHT1, 1);
- lmbind(LIGHT2, 2);
-
- zbuffer(TRUE);
- zclear();
- }
- else {
- zbuffer(FALSE);
- }
- }
- }
-
- /*****************************************************************************
- * Set up and draw a view window. *
- *****************************************************************************/
- static void SetViewWindow(void)
- {
- long PrefPos[4];
- static float Light1[] = {
- AMBIENT, 0.25, 0.25, 0.25,
- POSITION, 0.1, 0.5, 1.0, 0.0,
- LMNULL
- };
- static float Light2[] = {
- AMBIENT, 0.25, 0.25, 0.25,
- POSITION, 0.5, -1.5, -1.0, 0.0,
- LMNULL
- };
-
- #ifndef _AIX
- foreground();
- #endif
-
- if (sscanf(IGGlblViewPrefPos, "%ld, %ld, %ld, %ld",
- &PrefPos[0], &PrefPos[1], &PrefPos[2], &PrefPos[3]) == 4)
- prefposition(PrefPos[0], PrefPos[1], PrefPos[2], PrefPos[3]);
- else if (sscanf(IGGlblViewPrefPos, "%ld, %ld",
- &PrefPos[0], &PrefPos[1]) == 2)
- prefsize(PrefPos[0], PrefPos[1]);
- winopen("Poly3dView");
- winconstraints();
- wintitle("xGLdrvs");
- if (IGGlblDoDoubleBuffer)
- doublebuffer();
- else
- singlebuffer();
- RGBmode();
- if (IGGlblDepthCue) {
- # ifndef _AIX
- glcompat(GLC_ZRANGEMAP, 1);
- # endif /* _AIX */
- lRGBrange(0, 0, 0, 255, 255, 255, 0x0, 0x7fffff);
- depthcue(IGGlblDepthCue);
- }
- else
- depthcue(FALSE);
- if (IGGlblAntiAliasing) {
- # ifndef _AIX
- if (getgdesc(GD_PNTSMOOTH_CMODE) == 0 ||
- getgdesc(GD_BITS_NORM_DBL_CMODE) < 8)
- IGGlblAntiAliasing = FALSE;
- else {
- subpixel(TRUE);
- pntsmooth(SMP_ON);
- }
- # endif /* _AIX */
- }
- gconfig();
- getorigin(&ViewWinLeft, &ViewWinLow);
- getsize(&ViewWinWidth, &ViewWinHeight);
- ViewWinWidth2 = ViewWinWidth / 2;
- ViewWinHeight2 = ViewWinHeight / 2;
-
- ViewWinID = winget();
-
- concave(TRUE);
-
- /* Define necessary staff for Lighting. */
- lmdef(DEFMATERIAL, 1, 0, NULL);
- lmdef(DEFLMODEL, 1, 0, NULL);
- lmdef(DEFLIGHT, 1, sizeof(Light1) / sizeof(float), Light1);
- lmdef(DEFLIGHT, 2, sizeof(Light2) / sizeof(float), Light2);
-
- ClearViewArea();
- if (IGGlblDoDoubleBuffer)
- swapbuffers();
-
- /* This is wierd. without the sleep the gl get mixed up between the two */
- /* windows. If you have any idea why, let me know... */
- sleep(1);
- }
-
- /*****************************************************************************
- * Set up and draw a viewing window. *
- *****************************************************************************/
- static void RedrawViewWindow(void)
- {
- IPObjectStruct *PObj;
- Matrix CrntView;
- int i, j, k;
-
- ClearViewArea();
-
- if (IGGlblViewMode == IG_VIEW_PERSPECTIVE) {
- for (i = 0; i < 4; i++)
- for (j = 0; j < 4; j++) {
- CrntView[i][j] = 0;
- for (k = 0; k < 4; k++)
- CrntView[i][j] += IritPrsrViewMat[i][k] *
- IritPrsrPrspMat[k][j];
- }
- }
- else {
- for (i = 0; i < 4; i++)
- for (j = 0; j < 4; j++)
- CrntView[i][j] = IritPrsrViewMat[i][j];
- }
- loadmatrix(CrntView);
-
- for (PObj = IGGlblDisplayList; PObj != NULL; PObj = PObj -> Pnext)
- IGDrawObject(PObj);
-
- if (IGGlblDoDoubleBuffer)
- swapbuffers();
- }
-
- /******************************************************************************
- * Handle gl events *
- ******************************************************************************/
- static IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor)
- {
- static IGGraphicEventType
- LastEvent = IG_EVENT_NONE;
- static long
- LastX = -1;
- int i, TransformRequest,
- LeftButtonIsPressed = getbutton(LEFTMOUSE) == 1;
- IGGraphicEventType
- RetVal = IG_EVENT_NONE;
- short data;
- long x, y, dev;
- RealType XPos, YPos;
-
- /* Allow continuous drag on following events only: */
- if (LeftButtonIsPressed && !IG_IS_DRAG_EVENT(LastEvent)) {
- while (getbutton(LEFTMOUSE) == 1);
- LeftButtonIsPressed = FALSE;
- }
-
- if (LeftButtonIsPressed) {
- /* Allow leaving the Trans window if still pressed, and use last */
- /* event as the returned event. Note we wait until current position */
- /* is different from last one to make sure we do something. */
- while((x = getvaluator(MOUSEX) - TransWinLeft) == LastX &&
- getbutton(LEFTMOUSE) == 1);
- if (x != LastX) {
- *ChangeFactor = (((RealType) x) - LastX) / TransWinWidth2;
- LastX = x;
- return LastEvent;
- }
- else
- LeftButtonIsPressed = FALSE;
- }
-
- LastEvent = IG_EVENT_NONE;
-
- while (RetVal == IG_EVENT_NONE) {
- /* Wait for left button to be pressed in the Trans window. Note this */
- /* is the loop we are going to cycle in idle time. */
- for (TransformRequest = FALSE; !TransformRequest;) {
- x = getvaluator(MOUSEX);
- y = getvaluator(MOUSEY);
-
- if (qtest()) { /* Any external event occured? */
- switch (dev = qread(&data)) {
- case REDRAW:
- if (data == ViewWinID) {
- getorigin(&ViewWinLeft, &ViewWinLow);
- getsize(&ViewWinWidth, &ViewWinHeight);
- ViewWinWidth2 = ViewWinWidth / 2;
- ViewWinHeight2 = ViewWinHeight / 2;
- reshapeviewport();
- ortho2(-0.5, ViewWinWidth - 0.5,
- -0.5, ViewWinHeight - 0.5);
- RedrawViewWindow();
- }
- else if (data == TransWinID) {
- winset(TransWinID);
- getorigin(&TransWinLeft, &TransWinLow);
- getsize(&TransWinWidth, &TransWinHeight);
- reshapeviewport();
- ortho2(-0.5, TransWinWidth - 0.5,
- -0.5, TransWinHeight - 0.5);
- TransWinWidth2 = TransWinWidth / 2;
- RedrawTransformWindow();
- winset(ViewWinID);
- }
- break;
- case RIGHTMOUSE:
- if (data &&
- IGHandleState(dopup(GlblStateMenu), FALSE)) {
- *ChangeFactor = 0.0;
- return IG_EVENT_STATE;
- }
- break;
- case LEFTMOUSE:
- TransformRequest = data;
- break;
- }
- continue;
- }
-
- /* Maybe we have something in communication socket. */
- if (!IGGlblStandAlone &&
- IGReadObjectsFromSocket(IGGlblViewMode, &IGGlblDisplayList))
- RedrawViewWindow();
-
- IritSleep(10); /* So we do not use all CPU on idle. */
- }
-
- x -= TransWinLeft;
- y -= TransWinLow;
-
- XPos = ((RealType) x) / TransWinWidth;
- YPos = ((RealType) y) / TransWinHeight;
-
- /* Make sure we are in bound in the X direction. */
- if (XPos < (1.0 - INTERACT_SUB_WINDOW_WIDTH) / 2.0 ||
- XPos > 1.0 - (1.0 - INTERACT_SUB_WINDOW_WIDTH) / 2.0)
- continue;
-
- /* Now search the sub window the event occured in. */
- for (i = 0; i < INTERACT_NUM_OF_SUB_WNDWS; i++) {
- if (InteractMenu.SubWindows[i].Y <= YPos &&
- InteractMenu.SubWindows[i].Y + INTERACT_SUB_WINDOW_HEIGHT >=
- YPos) {
- RetVal = InteractMenu.SubWindows[i].Event;
- break;
- }
- }
- if (i == INTERACT_NUM_OF_SUB_WNDWS)
- continue;
-
- /* Take care of special cases in which the window should be updated. */
- switch (RetVal) {
- case IG_EVENT_SCR_OBJ_TGL:
- IGGlblTransformMode = IGGlblTransformMode == IG_TRANS_OBJECT ?
- IG_TRANS_SCREEN :
- IG_TRANS_OBJECT;
- RedrawTransformWindow();
- break;
- case IG_EVENT_PERS_ORTHO_TGL:
- IGGlblViewMode = IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
- IG_VIEW_ORTHOGRAPHIC :
- IG_VIEW_PERSPECTIVE;
- RedrawTransformWindow();
- break;
- case IG_EVENT_QUIT:
- break;
- }
-
- *ChangeFactor = (((RealType) x) - TransWinWidth2) / TransWinWidth2;
- }
-
- LastEvent = RetVal;
- LastX = x;
-
- return RetVal;
- }
- /******************************************************************************
- * Handle the event of a pop up window. *
- ******************************************************************************/
- int IGHandleState(int State, int Refresh)
- {
- int UpdateView = TRUE;
-
- switch (State) {
- case IG_STATE_SCR_OBJ_TGL:
- IGGlblTransformMode = IGGlblTransformMode == IG_TRANS_OBJECT ?
- IG_TRANS_SCREEN :
- IG_TRANS_OBJECT;
- RedrawTransformWindow();
- UpdateView = FALSE;
- break;
- case IG_STATE_PERS_ORTHO_TGL:
- IGGlblViewMode = IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
- IG_VIEW_ORTHOGRAPHIC :
- IG_VIEW_PERSPECTIVE;
- RedrawTransformWindow();
- break;
- case IG_STATE_DRAW_SOLID:
- IGGlblDrawSolid = !IGGlblDrawSolid;
- /* And fall thru to disable the depth cueing. */
- IGGlblDepthCue = TRUE;
- case IG_STATE_DEPTH_CUE:
- IGGlblDepthCue = !IGGlblDepthCue;
- if (IGGlblDepthCue) {
- # ifndef _AIX
- glcompat(GLC_ZRANGEMAP, 1);
- # endif /* _AIX */
- lRGBrange(0, 0, 0, 255, 255, 255,
- 0x0, 0x7fffff);
- depthcue(IGGlblDepthCue);
- }
- else
- depthcue(FALSE);
- break;
- case IG_STATE_DOUBLE_BUFFER:
- IGGlblDoDoubleBuffer = !IGGlblDoDoubleBuffer;
- winset(ViewWinID);
- if (IGGlblDoDoubleBuffer)
- doublebuffer();
- else
- singlebuffer();
- gconfig();
- break;
- case IG_STATE_ANTI_ALIASING:
- IGGlblAntiAliasing = !IGGlblAntiAliasing;
- # ifndef _AIX
- if (getgdesc(GD_PNTSMOOTH_CMODE) == 0 ||
- getgdesc(GD_BITS_NORM_DBL_CMODE) < 8)
- IGGlblAntiAliasing = FALSE;
- else
- subpixel(IGGlblAntiAliasing);
- # endif /* _AIX */
- break;
- case IG_STATE_FINER_APPROX:
- IGGlblSamplesPerCurve++;
- IGGlblFineNess++;
- IGActiveListFreeNamedAttribute("_polygons");
- IGActiveListFreeNamedAttribute("_adap_iso");
- IGActiveListFreeNamedAttribute("_isoline");
- break;
- case IG_STATE_COARSER_APPROX:
- IGGlblFineNess--;
- if (IGGlblFineNess < 2)
- IGGlblFineNess = 2;
- IGGlblSamplesPerCurve--;
- if (IGGlblSamplesPerCurve < 2)
- IGGlblSamplesPerCurve = 2;
- IGActiveListFreeNamedAttribute("_polygons");
- IGActiveListFreeNamedAttribute("_adap_iso");
- IGActiveListFreeNamedAttribute("_isoline");
- break;
- case IG_STATE_WIDER_LINES:
- IGGlblLineWidth *= 2;
- linewidth(IGGlblLineWidth);
- break;
- case IG_STATE_NARROW_LINES:
- IGGlblLineWidth /= 2;
- if (IGGlblLineWidth < 1)
- IGGlblLineWidth = 1;
- linewidth(IGGlblLineWidth);
- break;
- case IG_STATE_FINER_ADAP_ISO:
- GlblAdapIsoEps /= 2.0;
- IGActiveListFreeNamedAttribute("_adap_iso");
- break;
- case IG_STATE_COARSER_ADAP_ISO:
- GlblAdapIsoEps *= 2.0;
- IGActiveListFreeNamedAttribute("_adap_iso");
- break;
- case IG_STATE_FINER_RULED_SRF:
- GlblRuledSrfEps /= 2.0;
- IGActiveListFreeNamedAttribute("_adap_iso");
- break;
- case IG_STATE_COARSER_RULED_SRF:
- GlblRuledSrfEps *= 2.0;
- IGActiveListFreeNamedAttribute("_adap_iso");
- break;
- case IG_STATE_RULED_SRF_APPROX:
- GlblRuledSrfApprox = !GlblRuledSrfApprox;
- IGActiveListFreeNamedAttribute("_adap_iso");
- break;
- case IG_STATE_ADAP_ISO_DIR:
- if (IGGlblAdapIsoDir == CAGD_CONST_U_DIR)
- IGGlblAdapIsoDir = CAGD_CONST_V_DIR;
- else
- IGGlblAdapIsoDir = CAGD_CONST_U_DIR;
- IGActiveListFreeNamedAttribute("_adap_iso");
- break;
- default:
- UpdateView = IGDefaultStateHandler(State, Refresh);
- }
-
- if (Refresh && UpdateView)
- RedrawViewWindow();
-
- IGCreateStateMenu();
-
- return UpdateView;
- }
-
- /******************************************************************************
- * Draw text centered at the given position. *
- ******************************************************************************/
- static void DrawText(char *Str, long PosX, long PosY)
- {
- long Width = strwidth(Str);
-
- cmov2s(PosX - Width / 2, PosY - (getheight() / 2 - getdescender()));
- charstr(Str);
- }
-
- /****************************************************************************
- * Make noise function. *
- ****************************************************************************/
- void IGIritBeep(void)
- {
- ringbell();
- }
-